import React from 'react';
import { observer } from 'mobx-react';
import { observable } from 'mobx';
import app from '../../apis/app';
import { Tools } from 'weaver-mobile';
import { split, propsComToViewCom, convertToViewableComs } from './Helper';
import { isDataTable, isLayout } from './typeof';
import FieldView from './field/View';
import { viewTypes, comsType } from '../../constants/form';
import './index.less';

const getCurrentLabel = Tools.base64.getCurrentLabel;
const { FORM_HEADER } = comsType;
const { MOBILE } = viewTypes;

@observer
export default class FormComponents extends React.Component {
  @observable components = [];
  @observable loading = false;
  @observable formHeader = {config: {}};
  @observable fieldStyle = '';
  @observable titleStyle = '';

  componentDidMount() {
    this.getAjaxData();
  }

  getAjaxData = () => {
    const { appid } = this.props;
    let components = [];

    app.getDesign(appid).then(all => {
      const coms = all.main;
      
      this.fieldStyle = JSON.parse(all.style).field;
      this.titleStyle = JSON.parse(all.style).title;

      if (coms && coms.length) {
        coms.forEach(com => com.config = com.config || {});
        this.formHeader = coms.find(com => com.type === FORM_HEADER);
        components = convertToViewableComs(coms, all.sub);

        this.getComponents(components);
      }
    })
  }

  getComponents(components) {
    const allComs = [];

    if (!components) return [];

    components.forEach(com => {
      const { title, complex, coms = [], widths } = com.config;

      com.config.name = title || '';

      allComs.push(com)

      if (complex) {
        const subComs = split(com);

        allComs.push(...subComs);
      }

      if (coms.length) {
        if (isDataTable(com)) {
          const newComs = coms.filter((com, index) => {
            if (com) return true;

            widths && widths.splice(index, 1);
            return false;
          });

          allComs.push(...newComs);
        } else {

          allComs.push(...coms.filter(Boolean));

          coms.filter(Boolean).forEach(com => {
            if (com.config && com.config.complex) {
              const subComs = split(com);

              allComs.push(...subComs);
            }
          })
        }
      }
    });
    this.components = allComs.map(propsComToViewCom);
  }

  checkVisible = com => {
    const components = this.components;
    const childComs = com.config.coms;

    if (childComs && isLayout(com)) {
      return !!childComs.find(childCom => {
        if (childCom) {
          let child = components.find(component => component.uuid === childCom.uuid);
          return child.visible;
        }
        return false;
      });
    }

    return com.visible;
  }

  renderItem = (com, customProps = {}) => {
    if (!com) return null;

    if (com.pid) {
      const coms = this.components;
      const parentCom = coms.find(({ uuid }) => uuid === com.pid);

      if (isLayout(parentCom)) {
        com = coms.find(({ uuid }) => uuid === com.uuid);
      }
      if(isDataTable(parentCom)) {
        com.visible = true;
      }
    }

    if (!this.checkVisible(com)) return null;

    const { errorCom, error } = com;
    let theError = '';

    if (customProps.hasOwnProperty('error')) {
      theError = customProps.error;
    } else if (errorCom) {
      theError = errorCom.error;
    } else {
      theError = error;
    }

    return this.getFieldView(com, customProps,theError);
  }

  getFieldView(com, customProps) {
    const { shortkey } = this.props;
    const comProps = {
      viewType: MOBILE,
      key: com.uuid,
      field: com,
      shortkey: shortkey,
      fieldStyle: this.fieldStyle
    };

    // 多字段混合插件， 如地址
    if (com.config.complex) {
      return (
        <FieldView
          {...comProps}
          {...customProps}
        />
      );
    }

    // 布局插件，如明细子表
    if (com.config.coms) {
      return (
        <FieldView
          {...comProps}
          renderItem={this.renderItem}
        />
      );
    }

    return (
      <FieldView
        {...customProps}
        {...comProps}
      />
    );
  }

            
  render() {
    if (!this.components) return null;

    const {config} = this.formHeader;
    return (
      <div className='mobile-device fp_mobile wea-edc-app-mobile'
      >
        <div className='wea-edc-fv-main'>
          <div className='form-header' style={this.titleStyle.css}>
            {
              getCurrentLabel(config.title)
            }
          </div>
          {config.desc &&
              <p className='form-header-desc' dangerouslySetInnerHTML={{ __html: config.desc }} />
            }
          <div className='wea-edc-fv-body clearfix'>
            {this.components.filter(com => !com.pid && com.visible).map(com => {
              return this.renderItem(com);
            })}
          </div>
          <div className='mask'></div>
        </div>
      </div>
    );
  }
}